package com.vercer.engine.proxy;


import com.google.appengine.tools.development.ApiProxyLocalFactory;
import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.Delegate;
import com.google.apphosting.api.ApiProxy.Environment;

public class RemoteDatastore
{
	private static class RemoteContext
	{
		String id;
		String version;
		String path;
	}
	
	private static ThreadLocal<RemoteContext> threadRemoteContext = new ThreadLocal<RemoteContext>();
	
	public static void install()
	{
		install("no-local-appid-set", ".");
	}
	
	@SuppressWarnings("unchecked")
	public static void install(String appId, String warPath)
	{	
		Environment environment = ApiProxy.getCurrentEnvironment();
		if (environment == null)
		{
			System.out.println("Setting dummy environment");
			environment = new DummyEnvironment(appId);
		}
		
		ApiProxy.setEnvironmentForCurrentThread(new DelegatingEnvironment(environment)
		{
			@Override
			public String getVersionId() 
			{
				RemoteContext context = threadRemoteContext.get();
				if (context != null)
				{
					return context.version;
				}
				else
				{
					return super.getVersionId();
				}
			};
			
			@Override
			public String getAppId()
			{
				RemoteContext context = threadRemoteContext.get();
				if (context != null)
				{
					return context.id;
				}
				else
				{
					return super.getAppId();
				}
			}
		});
		
		Delegate<Environment> delegate = ApiProxy.getDelegate();
		if (delegate == null)
		{
			System.out.println("Setting dummy local proxy delegate");
		    delegate = new ApiProxyLocalFactory().create(new DummyLocalServerEnvironment(warPath));
		}
		
		RemoteDatastoreProxyDelegate proxy = new RemoteDatastoreProxyDelegate(delegate, null)
		{
			@Override
			protected String getRemotePath()
			{
				return threadRemoteContext.get().path;
			}
			
			@Override
			protected boolean shouldHandleCall(String type)
			{
				return threadRemoteContext.get() != null && super.shouldHandleCall(type);
			}
		};
		ApiProxy.setDelegate(proxy);
	}
	
	public static void bypass()
	{
		threadRemoteContext.set(null);
	}
	
	public static void divert(String path, String appId, String version)
	{
		RemoteContext context =  new RemoteContext();
		context.id = appId;
		context.version = version;
		context.path = path;
		
		threadRemoteContext.set(context);
	}
}
